package leetcode.editor.cn;//给出两个 非空 的链表用来表示两个非负的整数。其中，它们各自的位数是按照 逆序 的方式存储的，并且它们的每个节点只能存储 一位 数字。
//
// 如果，我们将这两个数相加起来，则会返回一个新的链表来表示它们的和。 
//
// 您可以假设除了数字 0 之外，这两个数都不会以 0 开头。 
//
// 示例： 
//
// 输入：(2 -> 4 -> 3) + (5 -> 6 -> 4)
//输出：7 -> 0 -> 8
//原因：342 + 465 = 807
// 
// Related Topics 链表 数学 
// 👍 4536 👎 0


//leetcode submit region begin(Prohibit modification and deletion)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //头结点,head.next指向个位
        ListNode head = new ListNode(0);
        //最终的结果,因为head在循环过程中会更改位置,因此需要提前保存当前节点(next指向个位的节点)
        ListNode result = head;
        //进位的数值
        int carry = 0;
        //循环终止条件,l1和l2都为空时才终止
        while (l1 != null || l2 != null) {
            //一种方便的写法,如果满足l1=null,则返回冒号前面的,反之返回冒号后面的
            int x = l1 == null ? 0 : l1.val;
            int y = l2 == null ? 0 : l2.val;
            //相加的数值
            int sum = x + y + carry;
            //head的next的指针指向一个新的节点,数值为sum%10
            head.next = new ListNode(sum % 10);
            //进位carry等于sum/10
            carry = sum / 10;
            //如果l1!=null,需要移动指针,继续向下一位相加
            //如果l1==null,久没有l1.next了
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
            //head指针移动,继续计算下一位的数值
            head = head.next;
            //如果进位为1,则需要新建一个节点表示,如果不是最高位,后续会对当前数值覆盖
            //而如果当前是最高位,就会产生一个新的节点,而不会被后续覆盖
            if (carry == 1) {
                head.next = new ListNode(carry);
            }
        }
        //相当于最开始的头结点的next指针指向的节点(结果链表的个位)
        return result.next;
    }
}

//leetcode submit region end(Prohibit modification and deletion)
class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}
